{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 76,
   "metadata": {},
   "outputs": [],
   "source": [
    "import tkinter as tk\n",
    "from tkinter import filedialog,Canvas\n",
    "from PIL import ImageTk\n",
    "import cv2\n",
    "from modules import *\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 77,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 对图像进行预处理(根据相关论文)\n",
    "\n",
    "# 高斯滤波对图像进行平滑处理，以去除噪声：\n",
    "def Gauss(img):\n",
    "    blur = []\n",
    "    blur = cv2.GaussianBlur(img, (3,3), 0)\n",
    "    return(blur)\n",
    "    \n",
    "# 直方图均衡化进行图像增强\n",
    "def hist(img):\n",
    "    \n",
    "    hist,bins = np.histogram(img,256,[0,256])\n",
    "    cumul = np.cumsum(hist) #累积直方图（计算每个灰度级的累计像素数量）\n",
    "    # 均衡化\n",
    "          #归一化\n",
    "    cumul_normalized = (cumul - cumul.min()) * 255 / (cumul.max() - cumul.min())\n",
    "          #应用\n",
    "    img1 = np.interp(img,bins[:-1],cumul_normalized).astype(np.uint8)\n",
    "    return img1\n",
    "\n",
    "def cvt(img):\n",
    "    # 二值化处理(增亮消暗)\n",
    "    t = 127\n",
    "    for vals in img:\n",
    "        if vals>t:\n",
    "            vals = 255\n",
    "        else:\n",
    "            vals = 0\n",
    "    \n",
    "#下面的三个函数在复现论文3的预处理\n",
    "#线性灰度变换(自适应)\n",
    "def linear(img):\n",
    "    # 定义线性变换的参数 \n",
    "    r1, s1 = np.min(img), 0\n",
    "    r2, s2 = np.max(img), 255\n",
    "    print(r1)\n",
    "    print(r2)\n",
    "    # 计算线性变换的斜率和截距\n",
    "    slope = (s2 - s1) / (r2 - r1)\n",
    "    intercept = s1 - slope * r1\n",
    "\n",
    "    # 应用线性变换\n",
    "    transformed_image = np.clip((img - intercept) / slope, 0, 255).astype(np.uint8)\n",
    "    return transformed_image\n",
    "\n",
    "# 直方图均衡化：\n",
    "def hist(image):\n",
    "    # 计算图像的直方图\n",
    "    hist, bins = np.histogram(image, 256, [0, 256])\n",
    "    cdf = hist.cumsum()\n",
    "    cdf_normalized = (cdf - cdf.min()) * 255 / (cdf.max() - cdf.min())\n",
    "\n",
    "    # 创建直方图均衡化的图像\n",
    "    equalized_image = np.interp(image, bins[:-1], cdf_normalized).astype(np.uint8)\n",
    "\n",
    "    return equalized_image\n",
    "\n",
    "# 二值化处理\n",
    "def Otsu(img):\n",
    "    _, binary_image = cv2.threshold(img, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)\n",
    "    return binary_image\n",
    "\n",
    "# 形态学运算处理\n",
    "def xingtai(img,rho_max,rho_min):\n",
    "    # 连通区域标记\n",
    "    labels = measure.label(img, connectivity=2)\n",
    "    # 获取连通区域的属性\n",
    "    regions = measure.regionprops(labels)\n",
    "    # 初始化参数\n",
    "    Ncon = len(regions)\n",
    "    Aavg = np.mean([region.area for region in regions])\n",
    "    As = np.std([region.area for region in regions])\n",
    "\n",
    "    # 判别干扰因素的区域\n",
    "    for region in regions:\n",
    "        Ai = region.area\n",
    "        if Ai < Aavg - As:\n",
    "           # 点状噪声区域，填充为背景\n",
    "            img[labels == region.label] = 0\n",
    "        elif Ai > Aavg + As:\n",
    "        # 片状斑纹区域，填充为背景\n",
    "            img[labels == region.label] = 0\n",
    "        \n",
    "    # 重新标记连通区域\n",
    "    labels_cleaned = measure.label(img, connectivity=2)\n",
    "\n",
    "    # 判别文字区域\n",
    "    for region in measure.regionprops(labels_cleaned):\n",
    "        bbox = region.bbox\n",
    "        y_RB, x_RB, y_LT, x_LT = bbox\n",
    "        height = y_RB - y_LT\n",
    "        width = x_RB - x_LT\n",
    "        if height == 0 or width == 0:\n",
    "            continue\n",
    "        aspect_ratio = height / width\n",
    "        if aspect_ratio > rho_max or aspect_ratio < rho_min:\n",
    "        # 非文字区域，填充为背景\n",
    "            img[y_LT:y_RB, x_LT:x_RB] = 0\n",
    "    return img\n",
    "def Otsu(img):\n",
    "    img = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)\n",
    "    _, binary_image = cv2.threshold(img, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)\n",
    "    return binary_image\n",
    "\n",
    "def preprocess(img):\n",
    "    img = cv2.resize(img,(256,256))\n",
    "    # img = Gauss(img)\n",
    "    img = linear(img)\n",
    "    img = Otsu(img)\n",
    "    img = xingtai(img,10,0.1)\n",
    "    return img "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 78,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "35\n",
      "255\n",
      "0\n",
      "255\n",
      "0\n",
      "255\n"
     ]
    }
   ],
   "source": [
    "def open_image():\n",
    "    # 注意：图片文件的路径不能有中文\n",
    "    file_path = filedialog.askopenfilename()\n",
    "    if file_path:\n",
    "        filepath.set(file_path)\n",
    "        global image\n",
    "        image = cv2.imread(file_path)\n",
    "\n",
    "        # if image is None:\n",
    "        #     tk.messagebox.showerror(\"错误\", \"无法加载图像文件。\")\n",
    "        #     return\n",
    "        # if image_pre is None:\n",
    "        #     tk.message\n",
    "\n",
    "        image = preprocess(image)\n",
    "        # 生成预处理前的图像窗口\n",
    "        image = Image.fromarray(image)\n",
    "        image.save(file_path)\n",
    "        image = ImageTk.PhotoImage(image = image)\n",
    "        canvas.create_image(200, 200, anchor='center', image = image)\n",
    "        # canvas.image = image\n",
    "\n",
    "def run_detection():\n",
    "    # 清空画布\n",
    "    canvas.delete('all')\n",
    "    # 处理文件夹\n",
    "    if os.path.exists(''):\n",
    "        shutil.rmtree('')\n",
    "    # 构建命令行参数\n",
    "    command = f\"python detect.py --weights best.pt --source {filepath.get()}\"\n",
    "    # 执行命令\n",
    "    os.system(command)  \n",
    "    # 打开识别完成的图像\n",
    "    detected_image_path = os.path.join('root\\\\to\\\\your\\\\local\\\\yolov5\\\\runs\\\\detect\\\\exp', os.path.basename(filepath.get()))\n",
    "    # print(os.path.basename(image_path.get()))\n",
    "    global detected_image\n",
    "    detected_image = Image.open(detected_image_path)\n",
    "    detected_image = ImageTk.PhotoImage(detected_image)\n",
    "    canvas.create_image(200, 200, anchor='center', image = detected_image)\n",
    "    # canvas.image = detected_image\n",
    "\n",
    "root = tk.Tk()\n",
    "root.title(\"甲骨文文字检测\")\n",
    "\n",
    "filepath = tk.StringVar()\n",
    "\n",
    "canvas = Canvas(root,width=400,height=400)\n",
    "canvas.pack()\n",
    "\n",
    "open_button = tk.Button(root, text=\"打开图像\", command=open_image)\n",
    "open_button.pack()\n",
    "\n",
    "detect_button = tk.Button(root, text=\"检测文字\", command=run_detection)\n",
    "detect_button.pack()\n",
    "\n",
    "root.mainloop()"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Digital_image_processing",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.12.2"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
